package input;

import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.GraphicsDevice;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.MouseEvent;

import javax.swing.event.MouseInputListener;

/**
 * Handles the input of the keyboard and mouse. 
 * Compabilities as First Person-controller as well.
 * @author Team Deer
 */
public class InputManager implements MouseInputListener {
	
	private final KeyboardState currentKeyboardState = KeyboardState.getInstance();

	private boolean mouseIsClicked;
	private Point mousePosition = new Point();
	private final Robot robot;
	private final Dimension screenSize = java.awt.Toolkit.getDefaultToolkit()
			.getScreenSize();

	// Constructor
	/**
	 * Constructs a new InputManager
	 */
	public InputManager(final GraphicsDevice gDevice) throws AWTException {
		this.robot = new Robot(gDevice);
		this.mousePosition = new Point(this.screenSize.width / 2,
				this.screenSize.height / 2);
		this.robot.mouseMove(this.mousePosition.x, this.mousePosition.y);
		this.mouseIsClicked = false;
	}

	// Methods
	
	/**
	 * 
	 * @return the current keyboard state
	 */
	public KeyboardState getKeyboardState() {
		return this.currentKeyboardState;
	}

	@Override
	public void mouseDragged(final MouseEvent e) {
		// not used
	}

	@Override
	public void mouseMoved(final MouseEvent e) {
		this.mousePosition = e.getLocationOnScreen();
	}

	@Override
	public void mouseClicked(final MouseEvent e) {
		this.mouseIsClicked = true;
	}

	@Override
	public void mouseEntered(final MouseEvent e) {
		// not used
	}

	@Override
	public void mouseExited(final MouseEvent e) {
		// not used
	}

	@Override
	public void mousePressed(final MouseEvent e) {
		// not used
	}

	@Override
	public void mouseReleased(final MouseEvent e) {
		// not used
	}

	/**
	 * Returns the mouse movement since last poll.
	 * 
	 * @return how much the mouse have been moved since last call
	 */
	public Point pollMouseMovement() {
		final Point p = (Point) this.mousePosition.clone();
		p.x -= this.screenSize.width / 2;
		p.y -= this.screenSize.height / 2;
		this.robot.mouseMove(this.screenSize.width / 2,
				this.screenSize.height / 2);
		return p;
	}

	/**
	 * Resets the mouseposition. Needed for models using the poll
	 * 
	 */
	public void resetMousePosition() {
		this.robot.mouseMove(this.screenSize.width / 2,
				this.screenSize.height / 2);
	}

	/**
	 * 
	 * @return the mouse position
	 */
	public Point getMousePosition() {
		return this.mousePosition;
	}

	/**
	 * Returns whether the mouse is clicked and clears the mouse clicks
	 * 
	 * @return true if the mouse is clicked this call.
	 */
	public boolean mouseIsClicked() {
		if (this.mouseIsClicked) {
			this.mouseIsClicked = false;
			return true;
		}
		return false;
	}
}